#!/usr/bin/env python3
"""
智能HR系统 - 结构化日志配置模块
提供详细的阶段追踪、错误分析、性能监控功能
"""

import logging
import json
import time
import traceback
import uuid
from datetime import datetime
from pathlib import Path
from typing import Dict, Any, Optional, List
from functools import wraps
import contextvars
from enum import Enum

class LogLevel(Enum):
    """日志级别枚举"""
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"
    CRITICAL = "CRITICAL"

class Stage(Enum):
    """系统执行阶段枚举"""
    STARTUP = "STARTUP"
    INTERACTION = "INTERACTION"
    ORCHESTRATOR = "ORCHESTRATOR" 
    CANDIDATE_ANALYSIS = "CANDIDATE_ANALYSIS"
    DEEP_ANALYSIS = "DEEP_ANALYSIS"
    RECORD_KEEPING = "RECORD_KEEPING"
    WORKBENCH_UI = "WORKBENCH_UI"
    TOOL_EXECUTION = "TOOL_EXECUTION"
    COMPLETION = "COMPLETION"
    ERROR_HANDLING = "ERROR_HANDLING"

# 上下文变量，用于跟踪请求
request_id_var = contextvars.ContextVar('request_id', default=None)
stage_var = contextvars.ContextVar('stage', default=None)
user_id_var = contextvars.ContextVar('user_id', default=None)

class StructuredFormatter(logging.Formatter):
    """结构化日志格式化器"""
    
    def format(self, record):
        # 获取上下文信息
        request_id = request_id_var.get()
        stage = stage_var.get()
        user_id = user_id_var.get()
        
        # 构建结构化日志
        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "level": record.levelname,
            "logger": record.name,
            "message": record.getMessage(),
            "request_id": request_id,
            "stage": stage,
            "user_id": user_id,
            "module": record.module,
            "function": record.funcName,
            "line": record.lineno
        }
        
        # 添加异常信息
        if record.exc_info:
            log_entry["exception"] = {
                "type": record.exc_info[0].__name__,
                "message": str(record.exc_info[1]),
                "traceback": traceback.format_exception(*record.exc_info)
            }
        
        # 添加额外字段
        if hasattr(record, 'extra_data'):
            log_entry["extra_data"] = record.extra_data
            
        if hasattr(record, 'performance'):
            log_entry["performance"] = record.performance
            
        if hasattr(record, 'agent_info'):
            log_entry["agent_info"] = record.agent_info
        
        return json.dumps(log_entry, ensure_ascii=False, indent=2)

class HRLogger:
    """HR系统专用日志记录器"""
    
    def __init__(self, name: str = "hr_system"):
        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)
        
        # 清除现有处理器
        self.logger.handlers.clear()
        
        # 创建日志目录
        log_dir = Path(__file__).parent / "logs"
        log_dir.mkdir(exist_ok=True)
        
        # 文件处理器 - 结构化JSON格式
        self.json_file_handler = logging.FileHandler(
            log_dir / f"hr_system_{datetime.now().strftime('%Y%m%d')}.json",
            encoding='utf-8'
        )
        self.json_file_handler.setFormatter(StructuredFormatter())
        self.json_file_handler.setLevel(logging.DEBUG)
        
        # 文件处理器 - 人类可读格式
        self.text_file_handler = logging.FileHandler(
            log_dir / f"hr_system_{datetime.now().strftime('%Y%m%d')}.log",
            encoding='utf-8'
        )
        text_formatter = logging.Formatter(
            '%(asctime)s | %(levelname)-8s | %(name)-20s | [%(module)s:%(funcName)s:%(lineno)d] | %(message)s'
        )
        self.text_file_handler.setFormatter(text_formatter)
        self.text_file_handler.setLevel(logging.INFO)
        
        # 控制台处理器 - 彩色输出
        self.console_handler = logging.StreamHandler()
        console_formatter = ColoredFormatter(
            '%(asctime)s | %(levelname)-8s | %(name)-15s | %(message)s'
        )
        self.console_handler.setFormatter(console_formatter)
        self.console_handler.setLevel(logging.INFO)
        
        # 添加处理器
        self.logger.addHandler(self.json_file_handler)
        self.logger.addHandler(self.text_file_handler)
        self.logger.addHandler(self.console_handler)
    
    def set_context(self, request_id: str = None, stage: Stage = None, user_id: str = None):
        """设置日志上下文"""
        if request_id:
            request_id_var.set(request_id)
        if stage:
            stage_var.set(stage.value)
        if user_id:
            user_id_var.set(user_id)
    
    def stage_start(self, stage: Stage, message: str = "", extra_data: Dict[str, Any] = None):
        """记录阶段开始"""
        self.set_context(stage=stage)
        
        log_message = f"🚀 阶段开始 [{stage.value}]"
        if message:
            log_message += f" - {message}"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        record.extra_data = extra_data or {}
        record.extra_data["stage_event"] = "START"
        record.extra_data["stage_name"] = stage.value
        
        self.logger.handle(record)
    
    def stage_end(self, stage: Stage, message: str = "", extra_data: Dict[str, Any] = None):
        """记录阶段结束"""
        log_message = f"✅ 阶段完成 [{stage.value}]"
        if message:
            log_message += f" - {message}"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        record.extra_data = extra_data or {}
        record.extra_data["stage_event"] = "END"
        record.extra_data["stage_name"] = stage.value
        
        self.logger.handle(record)
    
    def agent_action(self, agent_name: str, action: str, details: Dict[str, Any] = None):
        """记录智能体动作"""
        log_message = f"🤖 智能体动作 [{agent_name}] - {action}"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        record.agent_info = {
            "agent_name": agent_name,
            "action": action,
            "details": details or {}
        }
        
        self.logger.handle(record)
    
    def tool_execution(self, tool_name: str, args: Dict[str, Any], result: Any = None, execution_time: float = None):
        """记录工具执行"""
        log_message = f"🔧 工具执行 [{tool_name}]"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        
        record.extra_data = {
            "tool_name": tool_name,
            "args": args,
            "result_type": type(result).__name__ if result else None,
            "result_summary": str(result)[:200] if result else None
        }
        
        if execution_time:
            record.performance = {
                "execution_time_ms": round(execution_time * 1000, 2)
            }
        
        self.logger.handle(record)
    
    def error(self, message: str, exception: Exception = None, extra_data: Dict[str, Any] = None):
        """记录错误"""
        log_message = f"❌ 错误 - {message}"
        
        exc_info = None
        if exception:
            exc_info = (type(exception), exception, exception.__traceback__)
        
        record = self.logger.makeRecord(
            self.logger.name, logging.ERROR, __file__, 0, log_message, (), exc_info
        )
        record.extra_data = extra_data or {}
        
        if exception:
            record.extra_data["error_type"] = type(exception).__name__
            record.extra_data["error_message"] = str(exception)
        
        self.logger.handle(record)
    
    def performance(self, operation: str, duration: float, extra_metrics: Dict[str, Any] = None):
        """记录性能指标"""
        log_message = f"⚡ 性能监控 [{operation}] - {duration:.2f}秒"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        
        record.performance = {
            "operation": operation,
            "duration_seconds": duration,
            "timestamp": datetime.now().isoformat()
        }
        
        if extra_metrics:
            record.performance.update(extra_metrics)
        
        self.logger.handle(record)
    
    def user_interaction(self, user_id: str, action: str, details: Dict[str, Any] = None):
        """记录用户交互"""
        log_message = f"👤 用户交互 [{user_id}] - {action}"
        
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, log_message, (), None
        )
        
        record.extra_data = {
            "interaction_type": "USER_ACTION",
            "user_id": user_id,
            "action": action,
            "details": details or {}
        }
        
        self.logger.handle(record)
    
    def info(self, message: str, extra_data: Dict[str, Any] = None):
        """记录信息"""
        record = self.logger.makeRecord(
            self.logger.name, logging.INFO, __file__, 0, message, (), None
        )
        if extra_data:
            record.extra_data = extra_data
        self.logger.handle(record)
    
    def warning(self, message: str, extra_data: Dict[str, Any] = None):
        """记录警告"""
        record = self.logger.makeRecord(
            self.logger.name, logging.WARNING, __file__, 0, message, (), None
        )
        if extra_data:
            record.extra_data = extra_data
        self.logger.handle(record)
    
    def debug(self, message: str, extra_data: Dict[str, Any] = None):
        """记录调试信息"""
        record = self.logger.makeRecord(
            self.logger.name, logging.DEBUG, __file__, 0, message, (), None
        )
        if extra_data:
            record.extra_data = extra_data
        self.logger.handle(record)

class ColoredFormatter(logging.Formatter):
    """彩色日志格式化器"""
    
    # ANSI颜色代码
    COLORS = {
        'DEBUG': '\033[36m',    # 青色
        'INFO': '\033[32m',     # 绿色
        'WARNING': '\033[33m',  # 黄色
        'ERROR': '\033[31m',    # 红色
        'CRITICAL': '\033[35m', # 紫色
        'RESET': '\033[0m'      # 重置
    }
    
    def format(self, record):
        # 获取颜色
        color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
        reset = self.COLORS['RESET']
        
        # 格式化消息
        formatted = super().format(record)
        
        # 添加颜色
        return f"{color}{formatted}{reset}"

def performance_monitor(operation_name: str = None):
    """性能监控装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            operation = operation_name or f"{func.__module__}.{func.__name__}"
            
            try:
                result = func(*args, **kwargs)
                duration = time.time() - start_time
                
                # 记录性能
                hr_logger.performance(operation, duration)
                
                return result
            except Exception as e:
                duration = time.time() - start_time
                hr_logger.performance(operation, duration, {"status": "error"})
                raise
        
        return wrapper
    return decorator

def async_performance_monitor(operation_name: str = None):
    """异步性能监控装饰器"""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            start_time = time.time()
            operation = operation_name or f"{func.__module__}.{func.__name__}"
            
            try:
                result = await func(*args, **kwargs)
                duration = time.time() - start_time
                
                # 记录性能
                hr_logger.performance(operation, duration)
                
                return result
            except Exception as e:
                duration = time.time() - start_time
                hr_logger.performance(operation, duration, {"status": "error"})
                raise
        
        return wrapper
    return decorator

def log_errors(logger: HRLogger = None):
    """错误日志装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                error_logger = logger or hr_logger
                error_logger.error(
                    f"函数 {func.__name__} 执行失败", 
                    exception=e,
                    extra_data={
                        "function": func.__name__,
                        "args": str(args)[:200],
                        "kwargs": str(kwargs)[:200]
                    }
                )
                raise
        return wrapper
    return decorator

# 创建全局日志实例
hr_logger = HRLogger("HR_SYSTEM")

# 日志统计类
class LogStats:
    """日志统计工具"""
    
    def __init__(self):
        self.stats = {
            "requests_total": 0,
            "errors_total": 0,
            "stages_completed": {},
            "tools_executed": {},
            "performance_metrics": {}
        }
    
    def increment_requests(self):
        self.stats["requests_total"] += 1
    
    def increment_errors(self):
        self.stats["errors_total"] += 1
    
    def record_stage_completion(self, stage: str):
        if stage not in self.stats["stages_completed"]:
            self.stats["stages_completed"][stage] = 0
        self.stats["stages_completed"][stage] += 1
    
    def record_tool_execution(self, tool_name: str):
        if tool_name not in self.stats["tools_executed"]:
            self.stats["tools_executed"][tool_name] = 0
        self.stats["tools_executed"][tool_name] += 1
    
    def get_stats(self) -> Dict[str, Any]:
        return self.stats.copy()

# 全局统计实例
log_stats = LogStats()

if __name__ == "__main__":
    # 测试日志系统
    hr_logger.set_context(
        request_id=str(uuid.uuid4()),
        stage=Stage.STARTUP,
        user_id="test_user"
    )
    
    hr_logger.stage_start(Stage.STARTUP, "系统启动测试")
    hr_logger.info("这是一个测试消息", {"test_data": "示例数据"})
    hr_logger.agent_action("TestAgent", "测试动作", {"param": "value"})
    hr_logger.tool_execution("test_tool", {"arg1": "value1"}, "结果", 0.123)
    hr_logger.performance("测试操作", 1.5, {"memory_usage": "100MB"})
    hr_logger.stage_end(Stage.STARTUP, "系统启动完成")
    
    print("日志系统测试完成，请查看logs目录下的日志文件")












